/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package gui;

import java.io.File;
import java.io.FileInputStream;

import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileFilter;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;

import com.sunshine.geek.bytecode.ClassFileParse;
import com.sunshine.geek.bytecode.ClassInfo;
import com.sunshine.geek.bytecode.struct.info.ConstPoolType;
import com.sunshine.geek.bytecode.struct.info.ConstUtf8Info;
import com.sunshine.geek.bytecode.struct.info.ConstsClassInfo;

/**
 *
 * @author zeqi.cw
 */
public class ClassReaderGUI extends javax.swing.JFrame {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private ClassFileParse parse = new ClassFileParse();
	private ClassInfo classInfo = null;
	/**
	 * Creates new form NewJFrame1
	 */
	public ClassReaderGUI() {
		buildTreeNode(null);
		initComponents();
	}

	/**
	 * This method is called from within the constructor to initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is always
	 * regenerated by the Form Editor.
	 */
	@SuppressWarnings("unchecked")
	// <editor-fold defaultstate="collapsed" desc="Generated Code">
	private void initComponents() {

		jPanel1 = new javax.swing.JPanel();
		jScrollPane2 = new javax.swing.JScrollPane();
		jTextPane1 = new javax.swing.JTextPane();
		jScrollPane1 = new javax.swing.JScrollPane();
		jTree1 = new javax.swing.JTree(this.top);
		jMenuBar1 = new javax.swing.JMenuBar();
		jMenu1 = new javax.swing.JMenu();
		jMenuItem1 = new javax.swing.JMenuItem();
		jMenu2 = new javax.swing.JMenu();
		jMenuItem2 = new javax.swing.JMenuItem();
		
		setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

		jScrollPane2.setViewportView(jTextPane1);

		javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(
				jPanel1);
		jPanel1.setLayout(jPanel1Layout);
		jPanel1Layout.setHorizontalGroup(jPanel1Layout.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING).addGroup(
				javax.swing.GroupLayout.Alignment.TRAILING,
				jPanel1Layout
						.createSequentialGroup()
						.addComponent(jScrollPane2,
								javax.swing.GroupLayout.DEFAULT_SIZE, 418,
								Short.MAX_VALUE).addContainerGap()));
		jPanel1Layout.setVerticalGroup(jPanel1Layout.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING).addGroup(
				jPanel1Layout.createSequentialGroup().addContainerGap()
						.addComponent(jScrollPane2)));

		jTree1.setAutoscrolls(true);

		jScrollPane1.setViewportView(jTree1);

		jMenu1.setText("File");

		jMenuItem1.setText("Open");
		jMenuItem1.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jMenuItem1ActionPerformed(evt);
			}
		});
		jMenu1.add(jMenuItem1);

		jMenuBar1.add(jMenu1);

		jMenu2.setText("Help");

		jMenuItem2.setText("About");
		jMenuItem2.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jMenuItem2ActionPerformed(evt);
			}
		});
		jMenu2.add(jMenuItem2);

		jMenuBar1.add(jMenu2);

		setJMenuBar(jMenuBar1);

		javax.swing.GroupLayout layout = new javax.swing.GroupLayout(
				getContentPane());
		getContentPane().setLayout(layout);
		layout.setHorizontalGroup(layout
				.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGroup(
						javax.swing.GroupLayout.Alignment.TRAILING,
						layout.createSequentialGroup()
								.addComponent(jScrollPane1,
										javax.swing.GroupLayout.PREFERRED_SIZE,
										162,
										javax.swing.GroupLayout.PREFERRED_SIZE)
								.addPreferredGap(
										javax.swing.LayoutStyle.ComponentPlacement.RELATED)
								.addComponent(jPanel1,
										javax.swing.GroupLayout.DEFAULT_SIZE,
										javax.swing.GroupLayout.DEFAULT_SIZE,
										Short.MAX_VALUE)));
		layout.setVerticalGroup(layout
				.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGroup(
						layout.createSequentialGroup()
								.addGroup(
										layout.createParallelGroup(
												javax.swing.GroupLayout.Alignment.LEADING,
												false)
												.addComponent(
														jScrollPane1,
														javax.swing.GroupLayout.DEFAULT_SIZE,
														275, Short.MAX_VALUE)
												.addComponent(
														jPanel1,
														javax.swing.GroupLayout.DEFAULT_SIZE,
														javax.swing.GroupLayout.DEFAULT_SIZE,
														Short.MAX_VALUE))
								.addContainerGap(
										javax.swing.GroupLayout.DEFAULT_SIZE,
										Short.MAX_VALUE)));

		jTree1.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
			public void valueChanged(javax.swing.event.TreeSelectionEvent evt) {
				TreeNode node = (TreeNode) evt.getPath().getLastPathComponent();
				if (node.isLeaf()) {
					jTreeClick(node);
				}
			}
		});
		this.setTitle("java class reader");
		pack();
	}// </editor-fold>

	protected void jTreeClick(TreeNode node) {
		DefaultMutableTreeNode tNode = (DefaultMutableTreeNode) node;
		Object userObject = tNode.getUserObject();
		if(userObject instanceof ConstPoolType){
			ConstPoolType c  = (ConstPoolType) userObject;
			this.jTextPane1.setText(c.getDetail());
		}
	}

	private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {
		JFileChooser jfc = new JFileChooser();
		jfc.setFileSelectionMode(JFileChooser.FILES_ONLY);
		jfc.setCurrentDirectory(new File("d:/project/jvm/bin/c05"));
		jfc.setFileFilter(new FileFilter() {

			@Override
			public String getDescription() {
				// TODO Auto-generated method stub
				return "*.class";
			}

			@Override
			public boolean accept(File f) {
				if (f.isDirectory())
					return true;
				if (f.isFile() && f.getName().toLowerCase().endsWith(".class"))
					return true;
				return false;
			}
		});
		jfc.showDialog(new JLabel(), "select");
		File file = jfc.getSelectedFile();
		if (file == null)
			return;
		if (file.isDirectory()) {
			return;
		}

		if (file.isFile()) {

			String className = file.getName();
			className = className.substring(0, className.lastIndexOf("."));
			this.top.setUserObject(className);
			this.buildTreeNode(file.getAbsolutePath());
			this.jTree1.updateUI();
		}

	}

	private void jMenuItem2ActionPerformed(java.awt.event.ActionEvent evt) {
		JOptionPane.showMessageDialog(this,
				"class parse.\r\nmail to :tachyon@yeah.net");
	}

	private TreeNode buildTreeNode(String filePath) {
		
		if(filePath==null)
			return top;
		FileInputStream fis;
		try {
			fis = new FileInputStream(filePath);
			byte [] bytes = new byte[fis.available()];
			fis.read(bytes);
			fis.close();
			parse.setBytes(bytes);
			classInfo = parse.parseClassByte();
			
			
			
			//base Info
			DefaultMutableTreeNode baseInfo = new DefaultMutableTreeNode("General Information");
			top.add(baseInfo);
			//Const pool
			DefaultMutableTreeNode constPool = new DefaultMutableTreeNode("Constant Pool");
			for(int i=0;i<classInfo.getConstPools().size();i++)
			{
				
				ConstPoolType type = classInfo.getConstPools().get(i);
				if(type==null)
					continue;
				DefaultMutableTreeNode node = new DefaultMutableTreeNode(type);
				constPool.add(node);
			}
			top.add(constPool);
			//interface
			DefaultMutableTreeNode interfaces = new DefaultMutableTreeNode("Interfaces");
			for(int i=0;i<classInfo.getInterfacesCount();i++){
				int index = classInfo.getInterfaces().get(i);
				//classInfo.getConstPools().get(index).toString();
				String className= null;
				ConstPoolType temp = classInfo.getConstPools().get(index-1);
				if(temp instanceof ConstsClassInfo){
					ConstsClassInfo cc = (ConstsClassInfo) temp;
					index = cc.getIndex();
					ConstUtf8Info t = (ConstUtf8Info) classInfo.getConstPools().get(index-1);
					className = t.getContent();
				}else if(temp instanceof ConstUtf8Info){
					ConstUtf8Info t = (ConstUtf8Info) temp;
					className = t.getContent();
				}
				DefaultMutableTreeNode node = new DefaultMutableTreeNode(className);
				interfaces.add(node);
			}
			top.add(interfaces);
			
			DefaultMutableTreeNode fields = new DefaultMutableTreeNode("Fields");
			for(int i=0;i<classInfo.getFieldInfo().size();i++){
				
				DefaultMutableTreeNode node = new DefaultMutableTreeNode(classInfo.getFieldInfo().get(i));
				fields.add(node);
			}
			top.add(fields);
			
			//Method Info
			DefaultMutableTreeNode methods = new DefaultMutableTreeNode("Methods");
			for(int i=0;i<classInfo.getMethodInfo().size();i++){
				DefaultMutableTreeNode node = new DefaultMutableTreeNode(classInfo.getMethodInfo().get(i));
				methods.add(node);
			}
			top.add(methods);
			
			
			//Attribute
			DefaultMutableTreeNode attributes = new DefaultMutableTreeNode("Attributes");
			for(int i=0;i<classInfo.getAttribute().size();i++){
				DefaultMutableTreeNode node = new DefaultMutableTreeNode(classInfo.getAttribute().get(i));
				attributes.add(node);
			}
			top.add(attributes);
			
		} catch (Exception e) {
			e.printStackTrace();
			JOptionPane.showMessageDialog(null, "error:"+e.getMessage());
		}
		
		
		return top;
	}


	

	// Variables declaration - do not modify
	private javax.swing.JMenu jMenu1;
	private javax.swing.JMenu jMenu2;
	private javax.swing.JMenuBar jMenuBar1;
	private javax.swing.JMenuItem jMenuItem1;
	private javax.swing.JMenuItem jMenuItem2;
	private javax.swing.JPanel jPanel1;
	private javax.swing.JScrollPane jScrollPane1;
	private javax.swing.JScrollPane jScrollPane2;
	private javax.swing.JTextPane jTextPane1;
	private javax.swing.JTree jTree1;
	private DefaultMutableTreeNode top = new DefaultMutableTreeNode(
			"class reader");
	// End of variables declaration
}
